package com.tc.have_a_tired.ui;

import com.tc.have_a_tired.config.ConfigManager;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

/**
 * 休息倒计时窗口类
 * 显示休息倒计时，倒计时归零后自动关闭并触发回调
 */
public class RestCountdownWindow extends JDialog {

    private static final Color COLOR_PRIMARY = new Color(70, 130, 180);
    private static final Color COLOR_WARNING = new Color(255, 140, 0);
    private static final Color COLOR_DANGER = new Color(220, 20, 60);
    private static final Color COLOR_MESSAGE = new Color(100, 100, 100);

    private final Runnable onCountdownFinished;
    private final CountdownPanel countdownPanel;
    private Timer countdownTimer;
    private int remainingSeconds;
    private volatile boolean callbackTriggered = false;

    // 透明度缓存，避免频繁读取配置
    private float currentOpacity;

    // 拖拽相关变量
    private Point dragStartPoint;
    private Point windowStartLocation;

    public RestCountdownWindow(int restDurationMinutes, Runnable onCountdownFinished) {
        this.onCountdownFinished = onCountdownFinished;
        this.remainingSeconds = restDurationMinutes * 60;
        this.currentOpacity = ConfigManager.getCountdownOpacity();
        this.countdownPanel = new CountdownPanel(
                formatTime(remainingSeconds),
                "请好好休息",
                COLOR_PRIMARY,
                currentOpacity);

        initUI();
        startCountdown();
    }

    private void initUI() {
        setTitle("休息倒计时");
        setModal(false); // 非模态窗口，允许用户继续工作
        setAlwaysOnTop(true);
        setResizable(false);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

        // 设置为无装饰窗口，这样透明度才能生效
        setUndecorated(true);

        // 设置窗口大小（缩小，包含标题栏）
        setSize(220, 140);
        // 设置窗口位置到左下角
        setLocationToBottomLeft();

        // 设置窗口背景为透明（这样透明度才能生效）
        setBackground(new Color(0, 0, 0, 0));

        // 添加拖拽功能
        addDragSupport();

        // 创建内容面板，包含标题栏和关闭按钮
        JPanel contentPanel = new JPanel(new BorderLayout(0, 0));
        contentPanel.setOpaque(false);

        // 创建标题栏面板
        JPanel titlePanel = new JPanel(new BorderLayout());
        titlePanel.setOpaque(false);
        titlePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        // 标题标签
        JLabel titleLabel = new JLabel("休息倒计时");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
        titleLabel.setForeground(new Color(100, 100, 100));
        titlePanel.add(titleLabel, BorderLayout.WEST);

        // 关闭按钮
        JButton closeButton = new CloseButton();
        closeButton.addActionListener(e -> {
            // 停止倒计时
            stopCountdown();
            // 触发回调（开始下一轮工作时间）
            triggerCallbackIfNotTriggered();
            // 关闭窗口
            dispose();
        });
        titlePanel.add(closeButton, BorderLayout.EAST);

        contentPanel.add(titlePanel, BorderLayout.NORTH);

        JPanel centerWrapper = new JPanel(new BorderLayout());
        centerWrapper.setOpaque(false);
        centerWrapper.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
        centerWrapper.add(countdownPanel, BorderLayout.CENTER);

        contentPanel.add(centerWrapper, BorderLayout.CENTER);

        add(contentPanel);

        // 设置窗口关闭时的行为
        addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
                // 停止倒计时
                stopCountdown();
                // 窗口关闭时，如果回调还没有触发，则触发回调开始下一轮工作时间
                triggerCallbackIfNotTriggered();
            }

            @Override
            public void windowClosed(java.awt.event.WindowEvent windowEvent) {
                // 确保倒计时已停止
                stopCountdown();
            }
        });
    }

    /**
     * 设置为预览模式（显示固定时间，不进行倒计时）
     * 
     * @param fixedTimeMinutes 固定的分钟数（用于显示）
     */
    public void setPreviewMode(int fixedTimeMinutes) {
        // 停止倒计时
        stopCountdown();
        // 设置固定时间
        remainingSeconds = fixedTimeMinutes * 60;
        // 更新显示
        SwingUtilities.invokeLater(this::refreshCountdownDisplay);
    }

    /**
     * 开始倒计时
     */
    private void startCountdown() {
        refreshCountdownDisplay();

        if (remainingSeconds <= 0) {
            SwingUtilities.invokeLater(() -> {
                dispose();
                triggerCallbackIfNotTriggered();
            });
            return;
        }

        if (countdownTimer != null && countdownTimer.isRunning()) {
            countdownTimer.stop();
        }

        countdownTimer = new Timer(1000, e -> {
            remainingSeconds--;
            if (remainingSeconds <= 0) {
                remainingSeconds = 0;
                refreshCountdownDisplay();
                stopCountdown();
                SwingUtilities.invokeLater(() -> {
                    dispose();
                    // 触发回调，开始下一轮工作时间
                    triggerCallbackIfNotTriggered();
                });
            } else {
                refreshCountdownDisplay();
            }
        });
        countdownTimer.setInitialDelay(1000);
        countdownTimer.start();
    }

    /**
     * 停止倒计时
     */
    private void stopCountdown() {
        if (countdownTimer != null) {
            countdownTimer.stop();
            countdownTimer = null;
        }
    }

    /**
     * 刷新倒计时展示内容
     */
    private void refreshCountdownDisplay() {
        int seconds = Math.max(0, remainingSeconds);
        String newText = formatTime(seconds);

        String message;
        Color color;
        if (seconds <= 10) {
            message = "休息即将结束";
            color = COLOR_DANGER;
        } else if (seconds <= 30) {
            message = "休息时间不多了";
            color = COLOR_WARNING;
        } else {
            message = "请好好休息";
            color = COLOR_PRIMARY;
        }

        countdownPanel.updateState(newText, message, color);
    }

    /**
     * 触发回调（如果还没有触发过）
     */
    private synchronized void triggerCallbackIfNotTriggered() {
        if (!callbackTriggered && onCountdownFinished != null) {
            callbackTriggered = true;
            onCountdownFinished.run();
        }
    }

    /**
     * 格式化时间为 MM:SS 格式
     */
    private String formatTime(int seconds) {
        int minutes = seconds / 60;
        int secs = seconds % 60;
        return String.format("%02d:%02d", minutes, secs);
    }

    /**
     * 将窗口放到左下角
     */
    private void setLocationToBottomLeft() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] gs = ge.getScreenDevices();

        // 获取主屏幕（通常第一个）
        GraphicsDevice gd = gs[0];
        Rectangle bounds = gd.getDefaultConfiguration().getBounds();

        // 计算左下角位置（留一些边距）
        int margin = 20;
        int x = bounds.x + margin;
        int y = bounds.y + bounds.height - getHeight() - margin;

        setLocation(x, y);
    }

    /**
     * 更新背景透明度（只影响背景，不影响文字）
     * 
     * @param opacity 不透明度值（0.0-1.0）
     */
    public void updateBackgroundOpacity(float opacity) {
        currentOpacity = Math.max(0f, Math.min(1f, opacity));
        countdownPanel.setBackgroundOpacity(currentOpacity);
        repaint();
    }

    /**
     * 添加拖拽支持
     * 允许用户通过鼠标拖拽窗口移动位置
     */
    private void addDragSupport() {
        // 为整个窗口添加鼠标监听器
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                // 记录拖拽开始时的鼠标位置和窗口位置
                dragStartPoint = e.getPoint();
                windowStartLocation = getLocation();
            }
        });

        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (dragStartPoint != null && windowStartLocation != null) {
                    // 计算鼠标移动的距离
                    int deltaX = e.getXOnScreen() - (windowStartLocation.x + dragStartPoint.x);
                    int deltaY = e.getYOnScreen() - (windowStartLocation.y + dragStartPoint.y);

                    // 更新窗口位置
                    int newX = windowStartLocation.x + deltaX;
                    int newY = windowStartLocation.y + deltaY;

                    // 确保窗口不会移出屏幕
                    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                    GraphicsDevice[] gs = ge.getScreenDevices();
                    if (gs.length > 0) {
                        Rectangle bounds = gs[0].getDefaultConfiguration().getBounds();
                        newX = Math.max(bounds.x, Math.min(newX, bounds.x + bounds.width - getWidth()));
                        newY = Math.max(bounds.y, Math.min(newY, bounds.y + bounds.height - getHeight()));
                    }

                    setLocation(newX, newY);
                }
            }
        });
    }

    private static final class CloseButton extends JButton {

        private boolean hover;
        private boolean pressed;

        private CloseButton() {
            setPreferredSize(new Dimension(20, 20));
            setMinimumSize(new Dimension(20, 20));
            setMaximumSize(new Dimension(20, 20));
            setOpaque(false);
            setContentAreaFilled(false);
            setBorderPainted(false);
            setFocusPainted(false);
            setCursor(new Cursor(Cursor.HAND_CURSOR));
            setToolTipText("关闭");

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    hover = true;
                    repaint();
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    hover = false;
                    repaint();
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    if (SwingUtilities.isLeftMouseButton(e)) {
                        pressed = true;
                        repaint();
                    }
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    if (pressed) {
                        pressed = false;
                        repaint();
                    }
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int size = Math.min(getWidth(), getHeight());
            int padding = size / 3;

            Color crossColor;
            if (!isEnabled()) {
                crossColor = new Color(160, 160, 160);
            } else if (pressed) {
                crossColor = new Color(200, 30, 30);
            } else if (hover) {
                crossColor = new Color(220, 20, 60);
            } else {
                crossColor = new Color(110, 110, 110);
            }

            if (hover || pressed) {
                Color bg = new Color(255, 0, 0, pressed ? 60 : 35);
                g2.setColor(bg);
                g2.fillOval(2, 2, getWidth() - 4, getHeight() - 4);
            }

            g2.setStroke(new BasicStroke(2f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.setColor(crossColor);
            g2.drawLine(padding, padding, getWidth() - padding, getHeight() - padding);
            g2.drawLine(getWidth() - padding, padding, padding, getHeight() - padding);

            g2.dispose();
        }
    }

    private static final class CountdownPanel extends JPanel {

        private static final int CORNER_RADIUS = 16;
        private static final int V_PADDING = 16;

        private final Font countdownFont = new Font("Microsoft YaHei", Font.BOLD, 32);
        private final Font messageFont = new Font("Microsoft YaHei", Font.PLAIN, 12);

        private String countdownText;
        private String messageText;
        private Color countdownColor;
        private float backgroundOpacity;

        private CountdownPanel(String countdownText, String messageText, Color countdownColor,
                float backgroundOpacity) {
            this.countdownText = countdownText;
            this.messageText = messageText;
            this.countdownColor = countdownColor;
            this.backgroundOpacity = Math.max(0f, Math.min(1f, backgroundOpacity));

            setOpaque(false);
            setDoubleBuffered(true);
            setPreferredSize(new Dimension(220, 100));
        }

        private void updateState(String countdownText, String messageText, Color countdownColor) {
            this.countdownText = countdownText;
            this.messageText = messageText;
            this.countdownColor = countdownColor;
            repaint();
        }

        private void setBackgroundOpacity(float opacity) {
            this.backgroundOpacity = Math.max(0f, Math.min(1f, opacity));
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int width = getWidth();
            int height = getHeight();

            int alpha = Math.round(backgroundOpacity * 255);
            Color backgroundColor = new Color(245, 245, 250, alpha);
            Color borderColor = new Color(200, 200, 200, alpha);

            g2.setComposite(AlphaComposite.SrcOver);
            g2.setColor(backgroundColor);
            g2.fillRoundRect(0, 0, width, height, CORNER_RADIUS, CORNER_RADIUS);

            g2.setColor(borderColor);
            g2.setStroke(new BasicStroke(1f));
            g2.drawRoundRect(0, 0, width - 1, height - 1, CORNER_RADIUS, CORNER_RADIUS);

            // 绘制倒计时文本
            g2.setFont(countdownFont);
            g2.setColor(countdownColor);
            FontMetrics countdownMetrics = g2.getFontMetrics();
            int countdownX = (width - countdownMetrics.stringWidth(countdownText)) / 2;
            int countdownY = V_PADDING + countdownMetrics.getAscent();
            g2.drawString(countdownText, countdownX, countdownY);

            // 绘制提示信息
            g2.setFont(messageFont);
            g2.setColor(COLOR_MESSAGE);
            FontMetrics messageMetrics = g2.getFontMetrics();
            int messageX = (width - messageMetrics.stringWidth(messageText)) / 2;
            int messageY = height - V_PADDING - messageMetrics.getDescent();
            g2.drawString(messageText, messageX, messageY);

            g2.dispose();
        }
    }

    @Override
    public void dispose() {
        stopCountdown();
        super.dispose();
    }
}
